/**
 *    Copyright (C) 2008  Victor Smirnov <aist11@gmail.com>
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License along
 *    with this program; if not, write to the Free Software Foundation, Inc.,
 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *    See LICENSE.exceptions in the root folder of this project for possible
 *    exceptions
 *
 */


#ifndef __PACKED_VALUE_MAP_SIZE_TEST_HPP__
#define __PACKED_VALUE_MAP_SIZE_TEST_HPP__

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/portability/Stream.h>

#include <cubefs/core/tools/packed_map.hpp>

using namespace std;

namespace cubefs {
namespace core {
namespace tests {
namespace packed_map_ns {


template<typename Constants>
class PackedMapTest : public CPPUNIT_NS::TestFixture
{
    CPPUNIT_TEST_SUITE(PackedMapTest);

    CPPUNIT_TEST(testRemove);
    CPPUNIT_TEST(testInsert);

    CPPUNIT_TEST_SUITE_END();



protected:

    typedef wrapper<long> lwrapper;
    typedef packed_value_map<long, lwrapper, Constants> Map;

    Map map;

    typedef typename Map::index_t index_t;
    typedef typename Map::key_t key_t;

public:

    PackedMapTest() {}

    void setUp() {
        for (index_t c = 0; c < map.max_size()/2; c++) {
            map.add(c*2);
        }

        map.reindex();
    }

    void tearDown() {}

    void testRemove() {
        index_t size = map.size();
        index_t count = 20;
        map.remove(10, count);
        CPPUNIT_ASSERT_EQUAL(map.size(), size - count);

        for (index_t c = map.size(); c < map.size() + count; c++) {
            CPPUNIT_ASSERT(map.key(c) == 0);
        }
    }

    void testInsert() {
        index_t size = map.size();
        index_t count = 1;

        map.insert_data(50, count, 88, lwrapper(54));

        CPPUNIT_ASSERT_EQUAL(map.size(), size + count);

        for (index_t c = 50; c < 50 + count; c++) {
            CPPUNIT_ASSERT(map.key(c) == 88);
            CPPUNIT_ASSERT(map.data(c) == 54);
        }

        map.remove(50, 1);

        CPPUNIT_ASSERT(map.key(50) != 88);
        CPPUNIT_ASSERT(map.data(50) != 54);
    }

};

} //packed_map_ns
} //tests
} //core
} //cubefs

#endif
